package com.tecent.weixin.mp.service;

import com.tecent.weixin.mp.bean.MpConfigure;
import com.tecent.weixin.mp.bean.PayNotifyData;
import com.tecent.weixin.mp.bean.PrePayData;
import com.tecent.weixin.mp.bean.UnifiedOrderReqData;
import com.tecent.weixin.utils.XmlJsonParser;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * Created by cqd on 2015-09-12.
 * 微信支付页面流程  1、生成支付授权页面  ->2用户点击之后获取用户的openid->3用户提交表单，统一支付接口返回前端需要的json数据
 * 2、
 */
@Service(value = "weChatPayService")
public class WeChatPayService {
    @Autowired
    WxMpService wxMpServiceImpl;
    @Autowired
    WeChatHttpClientService weChatHttpClientService;

    /**
     * 构建一个带有权限验证的页面
     *
     * @param url   指定的url地址 比如指定到controller资源路径为接收路径，可以根据request.get("code")
     *              来获取具体code,getWechatUser后在转到相应的界面
     * @param scope WxConsts
     *              OAUTH2_SCOPE_BASE = "snsapi_base";不弹出授权页面，直接跳转，只能获取用户openid
     *              OAUTH2_SCOPE_USER_INFO = "snsapi_userinfo";弹出授权页面，能获取微信用户所有的大部分信息
     * @param state 生成一个状态信息值有生成后的页面带过去
     *              <p/>
     *              String url = Constant.DOMAIN+"home/page/pay"; 跳转到自己的controller，以方便后台获取到用户的openid
     *              String redirectUrl = WeChatPayService.generateUrl(url, WxConsts.OAUTH2_SCOPE_BASE, null);
     */
    public String generateUrl(String url, String scope, String state) {
        String authorizationUrl = wxMpServiceImpl.oauth2buildAuthorizationUrl(url, scope, state);
        return authorizationUrl;
    }

    /**
     * 获取用户页面openid
     *
     * @param request 用户点击授权页面后，发送回来的请求信息(包含code参数的变量值)
     */
    public String getOpenid(HttpServletRequest request) throws Exception {
        String code = request.getParameter("code");
        WxMpOAuth2AccessToken accessToken = wxMpServiceImpl
                .oauth2getAccessToken(code);
        return accessToken.getOpenId();
    }

    /**
     * 统一支付jssdk接口
     *
     * @param body         商品名称或者订单生成的名称
     * @param out_trade_no 系统本身的订单号
     * @param total_fee    总价钱
     * @param notice_url   付款成功后的回调路径，需注意商户平台配置的路径下的子路径
     * @param openid       用户的授权id
     * @return 返回激活微信支付的参数值（json串）
     */
    public String getUnifiedPay(String body, String out_trade_no, int total_fee, String notice_url, String openid) throws Exception {
        UnifiedOrderReqData reqData = new UnifiedOrderReqData.UnifiedOrderReqDataBuilder(
                body, out_trade_no, total_fee, notice_url, MpConfigure.JsApiTradeType).setOpenid(openid).build();
        String str = weChatHttpClientService.doPostXml(MpConfigure.UNIFIED_ORDER_API, XmlJsonParser.toXML(reqData));
        PayNotifyData data = XmlJsonParser.getObjectFromXML(str, PayNotifyData.class);
        PrePayData prePayData = new PrePayData();
        prePayData.setPkg(data.getPrepay_id());
        String result = XmlJsonParser.toJson(prePayData);
        return result;
    }

    /**
     * 统一支付Native接口
     *
     * @param body         商品名称或者订单生成的名称
     * @param out_trade_no 系统本身的订单号
     * @param total_fee    总价钱
     * @param notice_url   付款成功后的回调路径，需注意商户平台配置的路径下的子路径
     * @param product_id   扫码之后返回的数值
     * @return 返回激活微信支付的参数值（json串）
     */
    public String getUnifiedNativePay(String body, String out_trade_no, int total_fee, String notice_url, String product_id) throws Exception {
        UnifiedOrderReqData reqData = new UnifiedOrderReqData.UnifiedOrderReqDataBuilder(
                body, out_trade_no, total_fee, notice_url, MpConfigure.NativeTradeType).setProduct_id(product_id).build();
        String str = weChatHttpClientService.doPostXml(MpConfigure.UNIFIED_ORDER_API, XmlJsonParser.toXML(reqData));
        PayNotifyData data = XmlJsonParser.getObjectFromXML(str, PayNotifyData.class);
        PrePayData prePayData = new PrePayData();
        prePayData.setPkg(data.getPrepay_id());
        String result = XmlJsonParser.toJson(prePayData);
        System.out.println("test wechat pay:" + result);
        return result;
    }

    /**
     * 返回微信二维码支付的二维码信息
     *
     * @param body
     * @param out_trade_no
     * @param total_fee
     * @param notice_url
     * @param product_id   必须 商品id
     * @return
     * @throws Exception
     */
    public String getCodeNativePay(String body, String out_trade_no, int total_fee, String notice_url, String product_id) throws Exception {
        UnifiedOrderReqData reqData = new UnifiedOrderReqData.UnifiedOrderReqDataBuilder(
                body, out_trade_no, total_fee, notice_url, MpConfigure.NativeTradeType).setProduct_id(product_id).build();
        String str = weChatHttpClientService.doPostXml(MpConfigure.UNIFIED_ORDER_API, XmlJsonParser.toXML(reqData));
//        PayNotifyData data = XmlJsonParser.getObjectFromXML(str, PayNotifyData.class); //todo bug xsteam 解析不了code_url 的数据
//        System.out.println("data:" + data);
        Map<String,String> map = XmlJsonParser.doXMLParse(str);
        return map.get("code_url");
    }
}
